package site.beanyon.now.aspect.log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import site.beanyon.now.model.dto.HttpResponse;
import site.beanyon.now.service.UserService;

import java.util.Map;

/**
 * 用户信息更新日志切面，用于记录用户信息的变更
 */
@Aspect
@Component
class UserLogAspect {
    private Logger logger = LoggerFactory.getLogger(UserLogAspect.class);

    @Autowired
    private UserService userService;

    /**
     * 插入用户（用于用户注册）
     *
     * @param jp 连接点
     * @return 是否插入成功
     */
    @Around("execution(* site.beanyon.now.service.UserService.insertUser(..))")
    private boolean insertUser(ProceedingJoinPoint jp) throws Throwable {
        // 插入前
        String tel = (String) jp.getArgs()[0];
        String password = (String) jp.getArgs()[1];
        String salt = (String) jp.getArgs()[2];

        boolean result = false;

        try {
            result = (boolean) jp.proceed();
        } catch (Throwable throwable) {
            // 插入异常
            logger.error("[error] insert user, tel=" + tel
                    + ", password=" + password
                    + ", salt=" + salt);
            throw throwable;
        }

        // 插入后
        logger.info("[success] insert user, tel=" + tel);

        return result;
    }

    /**
     * 用户登录切面
     *
     * @param jp 连接点
     * @return 登录结果
     */
    @Around("execution(* site.beanyon.now.controller.UserController.signIn(..))")
    private HttpResponse signIn(ProceedingJoinPoint jp) throws Throwable {
        // 登录前
        Map<String, String> params = (Map<String, String>) jp.getArgs()[0];
        String tel = params.get("tel");
        String psw = params.get("psw");

        HttpResponse httpResponse = null;

        try {
            // 执行登录操作
            httpResponse = (HttpResponse) jp.proceed();
        } catch (Throwable throwable) {
            // 登录异常
            logger.error("[error] user sign in, tel=" + tel
                    + ", psw=" + psw);
            throw throwable;
        }

        // 登录后
        logger.info("[success] user sign in, tel=" + tel);

        return httpResponse;
    }

    /**
     * 更新用户信息切面
     *
     * @param jp 连接点对象
     */
    @Around("execution(* site.beanyon.now.service.UserService.updateUserInfo(..))")
    private void updateUserInfo(ProceedingJoinPoint jp) throws Throwable {
        // 更新前
        String name = (String) jp.getArgs()[0];
        String birthday = (String) jp.getArgs()[1];
        String gender = (String) jp.getArgs()[2];

        try {
            // 执行更新用户信息方法
            jp.proceed();
        } catch (Throwable throwable) {
            // 更新异常
            logger.error("[error] update user info, name=" + name
                    + ", birthday=" + birthday
                    + ", gender=" + gender);
            throw throwable;
        }

        // 更新后
        logger.info("[success] update user info, name=" + name
                + ", birthday=" + birthday
                + ", gender=" + gender);
    }

    /**
     * 获取用户有登录行为的天数后执行
     *
     * @param jp 连接点对象
     */
    @Around("execution(* site.beanyon.now.service.UserService.getLoginDayCount(..))")
    private Integer getLoginDayCount(ProceedingJoinPoint jp) throws Throwable {
        // 获取前
        Integer userId = this.userService.getCurrentUser().getId();

        Integer dayCount = 0;

        try {
            // 获取
            dayCount = (Integer) jp.proceed();
        } catch (Throwable throwable) {
            // 获取异常
            logger.error("[error] get login day count, user_id=" + userId);
            throw throwable;
        }

        // 获取后
        logger.info("[success] get login day count, user_id=" + userId
                + ", dayCount=" + dayCount);

        return dayCount;
    }
}
